#include "interface.h"

void UserLEDInit(void) // 点亮PB0 LED灯函数
{
  GPIO_InitTypeDef GPIO_InitStructure; // 定义结构体变量

  GPIO_InitStructure.GPIO_Pin = LED_PIN;           // 选择你要设置的IO口
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置推挽输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(LED_GPIO, &GPIO_InitStructure);         // 初始化GPIO

  LED_SET; // 高电平 熄灭火LED灯
}

// 使能所有GPIO时钟
void GPIOCLKInit(void) {
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
}

void delay_init(void) {
  SysTick->CTRL &=
      0xfffffffb; // 控制寄存器，选择外部时钟即系统时钟的八分之一（HCLK/8；72M/8=9M）
}

// 1us 延时函数
void Delay_us(u32 Nus) {
  SysTick->LOAD = Nus * 9; // 时间加载    72M主频
  SysTick->CTRL |= 0x01;   // 开始倒数
  while (!(SysTick->CTRL & (1 << 16)))
    ;                         // 等待时间到达
  SysTick->CTRL = 0X00000000; // 关闭计数器
  SysTick->VAL = 0X00000000;  // 清空计数器
}

void Delayms(u32 Nms) {
  while (Nms--) {
    Delay_us(1000);
  }
}

// 红外光电对管初始化
void RedRayInit(void) {
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = SEARCH_M_PIN;   // 配置使能GPIO管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置GPIO模式,输入上拉
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(SEARCH_M_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = SEARCH_R_PIN;   // 配置使能GPIO管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置GPIO模式,输入上拉
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(SEARCH_R_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = SEARCH_L_PIN;   // 配置使能GPIO管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置GPIO模式,输入上拉
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(SEARCH_L_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = VOID_R_PIN;     // 配置使能GPIO管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置GPIO模式,输入上拉
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(VOID_R_GPIO, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = VOID_L_PIN;     // 配置使能GPIO管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 配置GPIO模式,输入上拉
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(VOID_L_GPIO, &GPIO_InitStructure);
}

void ServoInit(void) {
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = Servo_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(Servo_GPIO, &GPIO_InitStructure);

  Servo_SET; // 默认给高电位modfied by LC 2015.09.20 12:00
}

/**
 * @brief  Configures the NVIC for TIM2 interrupt.
 *
 * This function initializes the NVIC to handle TIM2 interrupts with a specified
 * priority and subpriority. It enables the TIM2 interrupt in the NVIC interrupt
 * controller.
 */
static void NVIC_TIM2Configuration(void) {
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Set the Vector Table base address at 0x08000000 */
  // NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);

  /* Enable the TIM5 gloabal Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);
}

/**
 * @brief  Initializes TIM2 peripheral.
 *
 * This function configures the TIM2 peripheral with a time base of 20us,
 * enabling its clock and setting up the timer with a 50kHz frequency.
 * It configures the timer to count upwards, sets the prescaler to achieve
 * a 1MHz timer clock, and clears any pending update interrupts.
 * The function also enables the update interrupt and starts the TIM2 counter.
 * Additionally, it sets up the NVIC for TIM2 interrupt handling.
 */
void TIM2_Init(void) {
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* Time base configuration */
  // 这个就是自动装载的计数值，由于计数是从0开始的，周期为20us
  TIM_TimeBaseStructure.TIM_Period = (20 - 1); // 50kHz
  // 这个就是预分频系数，当由于为0时表示不分频所以要减1
  TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1); // 1MHz
  // 高级应用本次不涉及。定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)
  // 使用的采样频率之间的分频比例
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  // 向上计数
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  // 初始化定时器5
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* Clear TIM5 update pending flag[清除TIM5溢出中断标志] */
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

  /* TIM IT enable */ // 打开溢出中断
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

  /* TIM5 enable counter */
  TIM_Cmd(TIM2, ENABLE); // 计数器使能，开始工作

  /* 中断参数配置 */
  NVIC_TIM2Configuration();
}

void LEDToggle(uint16_t Led) {
  /* 指定管脚输出异或 1，实现对应的LED指示灯状态取反目的 */
  // LED_GPIO->ODR ^= Led;
  // 若要提高效率，建议直接调用 LEDnOBB = !LEDnOBB;
}

#if LCD_MODULE_ENABLED
void FMInit(void) // FM灯函数
{
  GPIO_InitTypeDef GPIO_InitStructure; // 定义结构体变量

  GPIO_InitStructure.GPIO_Pin = FM_PIN;            // 选择你要设置的IO口
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置推挽输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIO端口速度
  GPIO_Init(FM_GPIO, &GPIO_InitStructure);          // 初始化GPIO

  FM_SET; // 高电平 熄灭火LED灯
}
#endif